package com.snails.net.restful.rx;

import android.content.Context;
import android.text.TextUtils;

import com.snails.net.utils.FileUtil;

import java.io.File;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;

/**
 * rx下载辅助器
 *
 * @author lawrence
 * @date 2019-04-15 10:30
 */
public class RxDownLoader {
    private RxRestClient rxClient = null;

    private RxDownLoader(final Context ctx, final Builder builder) {
        final Context appCtx = ctx.getApplicationContext();

        rxClient = new RxRestClient.Builder().url(builder.url)
                .headers(builder.headers).params(builder.params).build();

        rxClient.download().subscribeOn(Schedulers.io())    //请求网络 在调度者的io线程
                .observeOn(Schedulers.io())                 //指定线程保存文件
                .observeOn(Schedulers.computation())
                .map(new Function<ResponseBody, File>() {
                    @Override
                    public File apply(ResponseBody body) throws Exception {
                        String dir = builder.downloadDir;
                        if (TextUtils.isEmpty(dir)) {
                            dir = "down_loads";
                        }
                        return FileUtil.writeToDisk(body.byteStream(), appCtx, dir, builder.downloadFile);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(builder.observer);
    }

    // ================================================================================
    // --- ---
    // ================================================================================
    public static class Builder {
        private String url = "";
        private LinkedHashMap<String, Object> params = null;
        private Map<String, String> headers = null;
        private Observer<File> observer = null;

        private String downloadDir = "";
        private String downloadFile = "";

        public final Builder url(String url) {
            this.url = url;
            return this;
        }

        public final Builder params(Map<String, Object> params) {
            if (params != null && params.size() > 0) {
                if (this.params == null) {
                    this.params = new LinkedHashMap<>();
                }
                this.params.putAll(params);
            }
            return this;
        }

        public final Builder params(String key, Object value) {
            if (!TextUtils.isEmpty(key)) {
                if (this.params == null) {
                    this.params = new LinkedHashMap<>();
                }
                this.params.put(key, value);
            }
            return this;
        }

        public final Builder headers(Map<String, String> headers) {
            if (headers != null && headers.size() > 0) {
                if (this.headers == null) {
                    this.headers = new HashMap<>();
                }
                this.headers.putAll(headers);
            }
            return this;
        }

        public final Builder headers(String key, String value) {
            if (!TextUtils.isEmpty(key)) {
                if (this.headers == null) {
                    this.headers = new HashMap<>();
                }
                this.headers.put(key, value);
            }
            return this;
        }

        public final Builder headers(String key, Object value) {
            if (!TextUtils.isEmpty(key)) {
                if (this.headers == null) {
                    this.headers = new HashMap<>();
                }
                this.headers.put(key, value == null ? "" : String.valueOf(value));
            }
            return this;
        }

        public final Builder observer(Observer<File> observer) {
            this.observer = observer;
            return this;
        }

        public final Builder downloadFile(String dir, String fileName) {
            this.downloadDir = dir;
            if (TextUtils.isEmpty(fileName)) {
                throw new NullPointerException("fileName 不能为空.");
            } else {
                this.downloadFile = fileName;
            }
            return this;
        }

        public final RxDownLoader build(Context ctx) {
            return new RxDownLoader(ctx, this);
        }

    }

}
